/* **********************************************************************************
 *
 * Copyright (c) TMF.AscendedThemeKit.Unthemed.NET Project. All rights reserved.
 *
 * This source code is subject to terms and conditions of the Shared Source License
 * for TMF.AscendedThemeKit.Unthemed. A copy of the license can be found in the License.html file
 * at the root of this distribution. If you can not locate the Shared Source License
 * for TMF.AscendedThemeKit.Unthemed, please send an email to ascendlic@<TBD>.
 * By using this source code in any fashion, you are agreeing to be bound by
 * the terms of the Shared Source License for TMF.AscendedThemeKit.Unthemed.NET.
 *
 * You must not remove this notice, or any other, from this software.
 *
 * **********************************************************************************/

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Text;
using System.Windows.Forms;

namespace TMF.AscendedThemeKit.Unthemed.Windows.Forms
{
    /// <summary>
    /// Renders a gradient background based on properties.
    /// </summary>
    public class GradientAnimationRender : IDisposable
    {
        private LinearGradientMode _gradientMode = LinearGradientMode.Vertical;
        private Color _gradientLowColor = SystemColors.MenuBar;
        private Color _gradientHighColor = SystemColors.Window;
        private CornerRadius _cornerRadius = new CornerRadius(0);
        private BorderColor _borderColor = new BorderColor(SystemColors.ActiveCaption);
        private Border _border = new Border(0);
        private SolidBrush _backBrush;
        private bool _antiAlias;
        private int _alpha = 255;
        private Color _adjustedLowColor;
        private Color _adjustedHighColor;
        private Color _adjustedBorderColorTop;
        private Color _adjustedBorderColorRight;
        private Color _adjustedBorderColorLeft;
        private Color _adjustedBorderColorBottom;
        private Color _adjustedBorderColorAll;
        private Rectangle _displayRectangle;
        private bool _enabled = true;
        private bool _disposed;
        private Bitmap _bitmap = null;
        private Graphics _graphics = null;
        private int _bitmapOffsetLocation;
        private int _bitmapOffset = 10;
        private bool _bitmapChange;

        /// <summary>
        /// Occurs when the GradientMode property changes.
        /// </summary>
        internal event EventHandler GradientModeChanged;

        /// <summary>
        /// Occurs when the GradientLowColor property changes.
        /// </summary>
        internal event EventHandler GradientLowColorChanged;

        /// <summary>
        /// Occurs when the GradientHighColor property changes.
        /// </summary>
        internal event EventHandler GradientHighColorChanged;

        /// <summary>
        /// Occurs when the CornerRadius property changes.
        /// </summary>
        internal event EventHandler CornerRadiusChanged;

        /// <summary>
        /// Occurs when the BorderColor property changes.
        /// </summary>
        internal event EventHandler BorderColorChanged;

        /// <summary>
        /// Occurs when the Border property changes.
        /// </summary>
        internal event EventHandler BorderChanged;

        /// <summary>
        /// Occurs when the AntiAlias property changes.
        /// </summary>
        internal event EventHandler AntiAliasChanged;

        /// <summary>
        /// Occurs when the Alpha property changes.
        /// </summary>
        internal event EventHandler AlphaChanged;

        /// <summary>
        /// Occurs when the Enabled property changes.
        /// </summary>
        internal event EventHandler EnabledChanged;

        /// <summary>
        /// Gets or sets the alpha (transparancy) level (0 - 255) of the fill of the control.
        /// </summary>
        public int Alpha
        {
            get
            {
                return this._alpha;

            }

            set
            {
                if (value == this._alpha)
                {
                    return;

                }

                if (value < 0) value = 0;
                if (value > 255) value = 255;

                this._alpha = value;

                this.CreateColors();
                //this.CreateBitmap();

                this.OnAlphaChanged(new EventArgs());

            }

        }

        /// <summary>
        /// Gets or sets the linear gradient background brush of the fill of the control.
        /// </summary>
        public SolidBrush BackBrush
        {
            get
            {
                return this._backBrush;

            }

            set
            {
                if (value == this._backBrush)
                {
                    return;

                }

                this._backBrush = value;

            }

        }

        /// <summary>
        /// Gets or sets if there is a bitmap change.
        /// </summary>
        public bool BitmapChange
        {
            get 
            { 
                return this._bitmapChange;
            
            }

            set 
            { 
                this._bitmapChange = value;
            
            }

        }

        /// <summary>
        /// Gets or sets the amount the bitmap is offset with each move.
        /// </summary>
        /// <value>
        /// 	<para>
        /// System.int . Specifies the amount the bitmap is offset with each move.
        /// </para>
        /// 	<para>
        /// This property is read/write. 
        /// </para>
        /// </value>
        public int BitmapOffset
        {
            get
            {
                return this._bitmapOffset;

            }

            set
            {
                if (value == this._bitmapOffset)
                {
                    return;

                }

                this._bitmapOffset = value;

            }

        }

        /// <summary>
        /// Specifies the direction of a linear gradient.
        /// </summary>
        /// <value>
        /// 	<para>
        /// System.Drawing.Drawing2D.LinearGradientMode . Specifies the direction of a linear gradient.
        /// </para>
        /// 	<para>
        /// This property is read/write. 
        /// </para>
        /// </value>
        public LinearGradientMode GradientMode
        {
            get
            {
                return this._gradientMode;

            }

            set
            {
                if (value == this._gradientMode)
                {
                    return;

                }

                this._gradientMode = value;
                //this.CreateBitmap();

                this.OnGradientModeChanged(new EventArgs());

            }

        }

        /// <summary>
        /// Gets or sets the gradient low (darker) color for the control.
        /// </summary>
        /// <value>
        /// 	<para>
        /// System.Drawing.Color . A Color that represents the gradient low color of the control.
        /// </para>
        /// 	<para>
        /// This property is read/write. 
        /// </para>
        /// </value>
        public Color GradientLowColor
        {
            get
            {
                return this._gradientLowColor;

            }

            set
            {
                if (value == this._gradientLowColor)
                {
                    return;

                }

                this._gradientLowColor = value;

                this.CreateColors();
                //this.CreateBitmap();

                this.OnGradientLowColorChanged(new EventArgs());

            }

        }

        /// <summary>
        /// Gets or sets the gradient high (lighter) color for the control.
        /// </summary>
        /// <value>
        /// 	<para>
        /// System.Drawing.Color . A Color that represents the gradient high color of the control.
        /// </para>
        /// 	<para>
        /// This property is read/write. 
        /// </para>
        /// </value>
        public Color GradientHighColor
        {
            get
            {
                return this._gradientHighColor;

            }

            set
            {
                if (value == this._gradientHighColor)
                {
                    return;

                }

                this._gradientHighColor = value;

                this.CreateColors();
                //this.CreateBitmap();

                this.OnGradientHighColorChanged(new EventArgs());

            }

        }

        /// <summary>
        /// gets or sets the graphics object for the class.
        /// </summary>
        public Graphics Graphics
        {
            get
            {
                return this._graphics;

            }

            set
            {
                this._graphics = value;

            }

        }

        /// <summary>
        /// Gets or sets the corner radius for the control.
        /// </summary>
        /// <value>
        /// 	<para>
        /// CornerRadius. An object of type CornerRadius representing the control's corner radius characteristics.
        /// </para>
        /// 	<para>
        /// This property is read/write.
        /// </para>
        /// </value>
        /// <remarks>
        /// For containers such as GradientPanel and GradientCaption, the CornerRadius property gets or sets their respective corner radius inside the DisplayRectangle.
        /// </remarks>
        public CornerRadius CornerRadius
        {
            get
            {
                return this._cornerRadius;

            }

            set
            {
                if (value == this.CornerRadius)
                {
                    return;

                }

                this._cornerRadius = value;

                this.OnCornerRadiusChanged(new EventArgs());

            }

        }

        /// <summary>
        /// Gets or sets the border color(s) for the control.
        /// </summary>
        /// <value>
        /// 	<para>
        /// BorderColor. An object of type Border representing the control's border color characteristics.
        /// </para>
        /// 	<para>
        /// This property is read/write.
        /// </para>
        /// </value>
        /// <remarks>
        /// For containers such as GradientPanel and GradientCaption, the BorderColor property gets or sets their respective border colors inside the DisplayRectangle.
        /// </remarks>
        public BorderColor BorderColor
        {
            get
            {
                return this._borderColor;

            }

            set
            {
                if (value == this._borderColor)
                {
                    return;

                }

                this._borderColor = value;

                this.CreateColors();

                this.OnBorderColorChanged(new EventArgs());

            }

        }

        /// <summary>
        /// Gets or sets the border for the control.
        /// </summary>
        /// <value>
        /// 	<para>
        /// Border. An object of type Border representing the control's border width characteristics.
        /// </para>
        /// 	<para>
        /// This property is read/write.
        /// </para>
        /// </value>
        /// <remarks>
        /// For containers such as GradientPanel and GradientCaption, the Border property gets or sets their respective border widths inside the DisplayRectangle.
        /// </remarks>
        public Border Border
        {
            get
            {
                return this._border;

            }

            set
            {
                if (value == this.Border)
                {
                    return;

                }

                this._border = value;

                this._bitmapOffsetLocation = this._border.Left;

                //this.CreateBitmap();

                this.OnBorderChanged(new EventArgs());

            }

        }

        /// <summary>
        /// Specifies the rendering hint for the control.
        /// </summary>
        /// <value>
        /// 	<para>
        /// System.Boolean . Specifies if the rendering should use antialiasing.
        /// </para>
        /// 	<para>
        /// This property is read/write. 
        /// </para>
        /// </value>
        public bool AntiAlias
        {
            get
            {
                return this._antiAlias;

            }

            set
            {
                if (value == this._antiAlias)
                {
                    return;

                }

                this._antiAlias = value;

                this.CreateColors();
                //this.CreateBitmap();

                this.OnAntiAliasChanged(new EventArgs());

            }

        }

        /// <summary>
        /// Gets or sets a value indicating whether the control can respond to user interaction.
        /// </summary>
        /// <value>
        /// 	<para>
        /// System.Boolean . true if the control can respond to user interaction; otherwise, false. The default is true. 
        /// </para>
        /// 	<para>
        /// This property is read/write. 
        /// </para>
        /// </value>
        public bool Enabled
        {
            get
            {
                return this._enabled;

            }

            set
            {
                if (value == this._enabled)
                {
                    return;

                }

                this._enabled = value;

                this.CreateColors();
                //this.CreateBitmap();

            }

        }

        /// <summary>
        /// The display rectangle to render to.
        /// </summary>
        public Rectangle DisplayRectangle
        {
            get
            {
                return this._displayRectangle;

            }

            set
            {
                this._displayRectangle = value;

            }

        }

        /// <summary>
        /// Creates the colors used to draw the control.
        /// </summary>
        /// <remarks>
        /// Takes the alpha and enabled into account.
        /// </remarks>
        protected void CreateColors()
        {
            if (this.Enabled)
            {
                this._adjustedHighColor = Color.FromArgb(this._alpha, this._gradientHighColor);
                this._adjustedLowColor = Color.FromArgb(this._alpha, this._gradientLowColor);

                if (this._borderColor.ShouldSerializeAll())
                {
                    this._adjustedBorderColorAll = Color.FromArgb(this._alpha, this._borderColor.All);

                    this._adjustedBorderColorLeft = this._adjustedBorderColorAll;
                    this._adjustedBorderColorTop = this._adjustedBorderColorAll;
                    this._adjustedBorderColorRight = this._adjustedBorderColorAll;
                    this._adjustedBorderColorBottom = this._adjustedBorderColorAll;

                }
                else
                {
                    this._adjustedBorderColorLeft = Color.FromArgb(this._alpha, this._borderColor.Left);
                    this._adjustedBorderColorTop = Color.FromArgb(this._alpha, this._borderColor.Top);
                    this._adjustedBorderColorRight = Color.FromArgb(this._alpha, this._borderColor.Right);
                    this._adjustedBorderColorBottom = Color.FromArgb(this._alpha, this._borderColor.Bottom);

                }

            }
            else
            {
                ExtendedColor grayscaleHigh = new ExtendedColor(this._gradientHighColor, 0.0d);
                ExtendedColor grayscaleLow = new ExtendedColor(this._gradientLowColor, 0.0d);
                grayscaleHigh.Alpha = (byte)this._alpha;
                grayscaleLow.Alpha = (byte)this._alpha;

                this._adjustedHighColor = grayscaleHigh;
                this._adjustedLowColor = grayscaleLow;

                if (this._borderColor.ShouldSerializeAll())
                {
                    ExtendedColor grayscaleBorderAll = new ExtendedColor(this._borderColor.All, 0.0d);
                    grayscaleBorderAll.Alpha = (byte)this._alpha;
                    this._adjustedBorderColorAll = grayscaleBorderAll;

                }
                else
                {
                    ExtendedColor grayscaleBorderLeft = new ExtendedColor(this._borderColor.Left, 0.0d);
                    grayscaleBorderLeft.Alpha = (byte)this._alpha;
                    this._adjustedBorderColorLeft = grayscaleBorderLeft;

                    ExtendedColor grayscaleBorderTop = new ExtendedColor(this._borderColor.Top, 0.0d);
                    grayscaleBorderTop.Alpha = (byte)this._alpha;
                    this._adjustedBorderColorTop = grayscaleBorderTop;

                    ExtendedColor grayscaleBorderRight = new ExtendedColor(this._borderColor.Right, 0.0d);
                    grayscaleBorderRight.Alpha = (byte)this._alpha;
                    this._adjustedBorderColorRight = grayscaleBorderRight;

                    ExtendedColor grayscaleBorderBottom = new ExtendedColor(this._borderColor.Bottom, 0.0d);
                    grayscaleBorderBottom.Alpha = (byte)this._alpha;
                    this._adjustedBorderColorBottom = grayscaleBorderBottom;

                }

            }

        }

        /// <summary>
        /// Fires the event indicating that the control Alpha property has changed.  Inheriting controls should use this in favour of actually listening to the event, but should not forget to call base.OnAlphaChanged() to ensure that the event is still fired for external listeners.
        /// </summary>
        /// <param name="e">A System.EventArgs that contains the event data.</param>
        protected void OnAlphaChanged(System.EventArgs e)
        {
            if (this.AlphaChanged != null)
            {
                this.AlphaChanged(this, e);

            }

        }

        /// <summary>
        /// Fires the event indicating that the control antialias has changed.  Inheriting controls should use this in favour of actually listening to the event, but should not forget to call base.OnAntiAliasChanged() to ensure that the event is still fired for external listeners.
        /// </summary>
        /// <param name="e">A System.EventArgs that contains the event data.</param>
        protected void OnAntiAliasChanged(EventArgs e)
        {
            if (this.AntiAliasChanged != null)
            {
                this.AntiAliasChanged(this, e);

            }

        }

        /// <summary>
        /// Fires the event indicating that the control Border has changed.  Inheriting controls should use this in favour of actually listening to the event, but should not forget to call base.OnBorderChanged() to ensure that the event is still fired for external listeners.
        /// </summary>
        /// <param name="e">A System.EventArgs that contains the event data.</param>
        protected void OnBorderChanged(EventArgs e)
        {
            if (this.BorderChanged != null)
            {
                this.BorderChanged(this, e);

            }

        }

        /// <summary>
        /// Fires the event indicating that the control BorderColor has changed.  Inheriting controls should use this in favour of actually listening to the event, but should not forget to call base.OnBorderColorChanged() to ensure that the event is still fired for external listeners.
        /// </summary>
        /// <param name="e">A System.EventArgs that contains the event data.</param>
        protected void OnBorderColorChanged(EventArgs e)
        {
            if (this.BorderColorChanged != null)
            {
                this.BorderColorChanged(this, e);

            }

        }

        /// <summary>
        /// Fires the event indicating that the control CornerRadius has changed.  Inheriting controls should use this in favour of actually listening to the event, but should not forget to call base.OnCornerRadiusChanged() to ensure that the event is still fired for external listeners.
        /// </summary>
        /// <param name="e">A System.EventArgs that contains the event data.</param>
        protected void OnCornerRadiusChanged(EventArgs e)
        {
            if (this.CornerRadiusChanged != null)
            {
                this.CornerRadiusChanged(this, e);

            }

        }

        /// <param name="e">An System.EventArgs that contains the event data.</param>
        protected virtual void OnEnabledChanged(System.EventArgs e)
        {
            if (this.EnabledChanged != null)
            {
                this.EnabledChanged(this, e);

            }

        }

        /// <summary>
        /// Fires the event indicating that the control gradient high color has changed.  Inheriting controls should use this in favour of actually listening to the event, but should not forget to call base.OnGradientHighColorChanged() to ensure that the event is still fired for external listeners.
        /// </summary>
        /// <param name="e">A System.EventArgs that contains the event data.</param>
        protected void OnGradientHighColorChanged(EventArgs e)
        {
            if (this.GradientHighColorChanged != null)
            {
                this.GradientHighColorChanged(this, e);

            }

        }

        /// <summary>
        /// Fires the event indicating that the control gradient low color has changed.  Inheriting controls should use this in favour of actually listening to the event, but should not forget to call base.OnGradientLowColorChanged() to ensure that the event is still fired for external listeners.
        /// </summary>
        /// <param name="e">A System.EventArgs that contains the event data.</param>
        protected void OnGradientLowColorChanged(EventArgs e)
        {
            if (this.GradientLowColorChanged != null)
            {
                this.GradientLowColorChanged(this, e);

            }

        }

        /// <summary>
        /// Fires the event indicating that the control GradientMode has changed.  Inheriting controls should use this in favour of actually listening to the event, but should not forget to call base.OnGradientModeChanged() to ensure that the event is still fired for external listeners.
        /// </summary>
        /// <param name="e">A System.EventArgs that contains the event data.</param>
        protected void OnGradientModeChanged(EventArgs e)
        {
            if (this.GradientModeChanged != null)
            {
                this.GradientModeChanged(this, e);

            }

        }

        /// <summary>
        /// Initializes a new instance of the GradientBackground class.
        /// </summary>
        public GradientAnimationRender() : base()
        {
            this.CreateColors();

        }

        #region IDisposable Members

        /// <summary>
        /// Releases all resources used.
        /// </summary>
        public void Dispose()
        {
            this.Dispose(true);

            GC.SuppressFinalize(this);

            return;

        }

        /// <summary>
        /// Releases all resources used.
        /// </summary>
        /// <param name="disposing">true or false</param>
        protected virtual void Dispose(bool disposing)
        {
            if (!this._disposed)
            {
                if (disposing)
                {
                    if (this._backBrush != null) this._backBrush.Dispose();
                    if (this._bitmap != null) this._bitmap.Dispose();

                }

            }

            this._disposed = true;

        }

        #endregion


        #region IRender Members

        /// <summary>
        /// Renders the gradient background.
        /// </summary>
        /// <param name="e">Provides data for the Paint event.</param>
        public virtual void Render(PaintEventArgs e)
        {
            if (this.DisplayRectangle != null && e != null && e.Graphics != null)
            {
                if (this.DisplayRectangle.Width > 0 && this.DisplayRectangle.Height > 0)
                {
                    this._graphics = e.Graphics;

                    if ((this._bitmap == null) || this._bitmapChange) this.CreateBitmap();

                    Rectangle rectangle;

                    rectangle = this.DisplayRectangle;

                    if (this._gradientMode == LinearGradientMode.Horizontal)
                    {
                        rectangle.X = rectangle.Width - this._bitmapOffsetLocation;
                        rectangle.Width = this._bitmapOffsetLocation;

                        this._graphics.DrawImage(this._bitmap, this._bitmapOffsetLocation, this._border.Top, this.DisplayRectangle, GraphicsUnit.Pixel);
                        this._graphics.DrawImage(this._bitmap, this._border.Left, this._border.Top, rectangle, GraphicsUnit.Pixel);

                    }
                    else
                    {
                        rectangle.Y = rectangle.Height - this._bitmapOffsetLocation;
                        rectangle.Height = this._bitmapOffsetLocation;

                        this._graphics.DrawImage(this._bitmap, 0, this._bitmapOffsetLocation, this.DisplayRectangle, GraphicsUnit.Pixel);
                        this._graphics.DrawImage(this._bitmap, 0, 0, rectangle, GraphicsUnit.Pixel);

                    }

                    this.DrawSquareBackgound(e);

                }

            }

        }

        #endregion

        /// <summary>
        /// Sets the rendering hints based on the AntiAlias property.
        /// </summary>
        /// <remarks>
        /// This methid must be called before any drawing methods are called.
        /// </remarks>
        private void SetRenderingHints()
        {
            if (this._graphics != null)
            {
                if (this._antiAlias)
                {
                    this._graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
                    this._graphics.SmoothingMode = SmoothingMode.AntiAlias;

                }
                else
                {
                    this._graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SystemDefault;
                    this._graphics.SmoothingMode = SmoothingMode.Default;

                }

            }

        }

        /// <summary>
        /// Draws a square background.
        /// </summary>
        /// <param name="e">Provides data for the Paint event.</param>
        private void DrawSquareBackgound(PaintEventArgs e)
        {
            this._backBrush = new SolidBrush(Color.Transparent);

            Rectangle gradientBacground = new Rectangle((this.DisplayRectangle.Location.X - 1), this.DisplayRectangle.Location.Y, (this.DisplayRectangle.Width + 1), this.DisplayRectangle.Height);

            e.Graphics.FillRectangle(this._backBrush, gradientBacground);

            if (this._border.Top > 0)
            {
                Pen topBorderPen = new Pen(this._adjustedBorderColorTop, this._border.Top);
                try
                {
                    float offset = (float)(this._border.Top / 2.0);
                    e.Graphics.DrawLine(topBorderPen, new PointF(this.DisplayRectangle.Left, (this.DisplayRectangle.Top + offset)), new PointF((this.DisplayRectangle.Right - offset), (this.DisplayRectangle.Top + offset)));

                }
                catch
                {
                    throw;

                }
                finally
                {
                    topBorderPen.Dispose();

                }

            }

            if (this._border.Bottom > 0)
            {
                Pen botttomBorderPen = new Pen(this._adjustedBorderColorBottom, this._border.Bottom);
                try
                {
                    float offset = 0;

                    if (this._border.Bottom == 1)
                    {
                        offset = (float)this._border.Bottom;

                    }
                    else
                    {
                        offset = (float)Math.Floor((this._border.Bottom / 2.0));

                    }

                    e.Graphics.DrawLine(botttomBorderPen, new PointF(this.DisplayRectangle.Left, (this.DisplayRectangle.Bottom - offset)), new PointF((this.DisplayRectangle.Right - offset), (this.DisplayRectangle.Bottom - offset)));

                }
                catch
                {
                    throw;

                }
                finally
                {
                    botttomBorderPen.Dispose();

                }

            }

            if (this._border.Right > 0)
            {
                Pen rightBorderPen = new Pen(this._adjustedBorderColorRight, this._border.Right);
                try
                {
                    float offset = 0;

                    if (this._border.Right == 1)
                    {
                        offset = (float)this._border.Right;

                    }
                    else
                    {
                        offset = (float)Math.Floor((this._border.Right / 2.0));

                    }

                    e.Graphics.DrawLine(rightBorderPen, new PointF((this.DisplayRectangle.Right - offset), this.DisplayRectangle.Top), new PointF((this.DisplayRectangle.Right - offset), (this.DisplayRectangle.Bottom - offset)));

                }
                catch
                {
                    throw;

                }
                finally
                {
                    rightBorderPen.Dispose();

                }

            }

            if (this._border.Left > 0)
            {
                Pen leftBorderPen = new Pen(this._adjustedBorderColorLeft, this._border.Left);
                try
                {
                    float offset = (float)(this._border.Left / 2.0);
                    e.Graphics.DrawLine(leftBorderPen, new PointF((this.DisplayRectangle.Left + offset), this.DisplayRectangle.Top), new PointF((this.DisplayRectangle.Left + offset), this.DisplayRectangle.Bottom));

                }
                catch
                {
                    throw;

                }
                finally
                {
                    leftBorderPen.Dispose();

                }

            }

        }

        /// <summary>
        /// Gets or sets the adjusted high color for the control.
        /// </summary>
        /// <value>
        /// <para>
        /// System.Drawing.Color.
        /// </para>
        /// 	<para>
        /// This property is read/write.
        /// </para>
        /// </value>
        public Color AdjustedHighColor
        {
            get
            {
                return this._adjustedHighColor;

            }

            set
            {
                if (value == this._adjustedHighColor)
                {
                    return;

                }

                this._adjustedHighColor = value;

            }

        }

        /// <summary>
        /// Gets or sets the adjusted low color for the control.
        /// </summary>
        /// <value>
        /// <para>
        /// System.Drawing.Color.
        /// </para>
        /// 	<para>
        /// This property is read/write.
        /// </para>
        /// </value>
        public Color AdjustedLowColor
        {
            get
            {
                return this._adjustedLowColor;

            }

            set
            {
                if (value == this._adjustedLowColor)
                {
                    return;

                }

                this._adjustedLowColor = value;

            }

        }

        /// <summary>
        /// Resets the colors associated with the control.
        /// </summary>
        public virtual void ResetColors()
        {
            this.CreateColors();

        }

        private void CreateBitmap()
        {
            if (this._graphics != null)
            {
                if (this._displayRectangle.Width > 0 && this._displayRectangle.Height > 0)
                {
                    if (this._bitmap != null) this._bitmap.Dispose();

                    this.SetRenderingHints();
                    this.CreateColors();

                    this._bitmap = new Bitmap((this._displayRectangle.Width - (this._border.Left + this._border.Right)), ((this._displayRectangle.Height - (this._border.Top + this._border.Bottom)) + 1), this._graphics);

                    Rectangle rectangle1;
                    Rectangle rectangle2;
                    Brush brush1 = null;
                    Brush brush2 = null;

                    try
                    {
                        if (this._gradientMode == LinearGradientMode.Horizontal)
                        {
                            rectangle1 = this.DisplayRectangle;
                            rectangle1.Height += 2;
                            rectangle1.Width = this.DisplayRectangle.Width / 2 + 1;

                            rectangle2 = rectangle1;
                            rectangle2.Height += 2;
                            rectangle2.X = this.DisplayRectangle.Width / 2;
                            rectangle2.Width = this.DisplayRectangle.Width / 2 + 1;

                            brush1 = new LinearGradientBrush(rectangle1, this._adjustedHighColor, this._adjustedLowColor, this._gradientMode);
                            brush2 = new LinearGradientBrush(rectangle2, this._adjustedLowColor, this._adjustedHighColor, this._gradientMode);

                        }
                        else
                        {
                            rectangle1 = this.DisplayRectangle;
                            rectangle1.Height = this.DisplayRectangle.Height / 2 + 1;

                            rectangle2 = rectangle1;
                            rectangle2.Y = this.DisplayRectangle.Height / 2;
                            rectangle2.Height = this.DisplayRectangle.Height / 2 + 1;

                            brush1 = new LinearGradientBrush(rectangle1, this._adjustedHighColor, this._adjustedLowColor, this._gradientMode);
                            brush2 = new LinearGradientBrush(rectangle2, this._adjustedLowColor, this._adjustedHighColor, this._gradientMode);

                        }

                        Graphics graphics = Graphics.FromImage(this._bitmap);
                        try
                        {
                            graphics.FillRectangle(brush2, rectangle2);
                            graphics.FillRectangle(brush1, rectangle1);

                        }
                        catch
                        {
                            throw;

                        }
                        finally
                        {
                            graphics.Dispose();

                        }

                    }
                    catch
                    {
                        throw;

                    }
                    finally
                    {
                        if (brush1 != null) brush1.Dispose();
                        if (brush2 != null) brush2.Dispose();

                    }

                    this._bitmapChange = false;

                }

            }

        }

        /// <summary>
        /// Moves the bitmap location to next forward position.
        /// </summary>
        /// <remarks>
        /// Does not cause the control to render. The render method must be called.
        /// </remarks>
        public void MoveNext()
        {
            this._bitmapOffsetLocation += this._bitmapOffset;

            if (this._gradientMode == LinearGradientMode.Horizontal)
            {
                if (this._bitmapOffsetLocation > this.DisplayRectangle.Width)
                {
                    this._bitmapOffsetLocation = this._border.Left;

                }

            }
            else
            {
                if (this._bitmapOffsetLocation > this.DisplayRectangle.Height)
                {
                    this._bitmapOffsetLocation = this._border.Top;

                }

            }

        }

        /// <summary>
        /// Moves the bitmap location to previous position.
        /// </summary>
        /// <remarks>
        /// Does not cause the control to render. The render method must be called.
        /// </remarks>
        public void MovePrevious()
        {
            this._bitmapOffsetLocation -= this._bitmapOffset;

            if (this._gradientMode == LinearGradientMode.Horizontal)
            {
                if (this._bitmapOffsetLocation < 0)
                {
                    this._bitmapOffsetLocation = 0;

                }

            }
            else
            {
                if (this._bitmapOffsetLocation < 0)
                {
                    this._bitmapOffsetLocation = 0;

                }

            }

        }

    }

}
